import { useEffect, useRef } from 'react'
import { fromEvent, merge, Observable, of } from 'rxjs'
import { useEventCallback } from 'rxjs-hooks'
import { map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators'
import { useParamsStore } from '../../blocks/main/store'

const SCROLL_WIDTH = 20

export const useTableColumn = () => {
	const wrapRef = useRef<HTMLDivElement>(null)
	const refreshWidth = useParamsStore((state) => state.refreshFlag)
	let name_min_width = useRef(340)
	// let operate_min_width = useObservable(
	// 	() => window.MCC_SERVICE.config.tableItemActionIconsLength$.pipe(map((length) => length * 28 + 8)),
	// 	8 * 28 + 8
	// )
	const operate_min_width = useParamsStore((state) => {
		const { mt, meeting, subMt } = state.tableItemAction
		if (mt.icon.length + mt.dropDown.length === 0) return 8 * 28 + 8
		return (Math.max(mt.icon.length, meeting.icon.length, subMt.icon.length) + 1) * 28 + 8
	})
	const status_min_width = useRef(5 * 25 + 8)
	let name_width = useRef(useParamsStore.getState().tableWidth.nameWidth || 0)
	let operate_width = useRef(useParamsStore.getState().tableWidth.operateWidth || 0)
	let status_width = useRef(useParamsStore.getState().tableWidth.statusWidth || 0)
	useEffect(() => {
		if (wrapRef) {
			const wrapStyle = getComputedStyle(wrapRef.current as Element)
			const wrapWidth = parseFloat(wrapStyle.getPropertyValue('width'))
			if (isNaN(wrapWidth) || wrapWidth <= 100) return
			const oneThirdWidth = (wrapWidth - SCROLL_WIDTH) / 3
			if (operate_width.current === 0) {
				operate_width.current = oneThirdWidth
			}
			if (status_width.current === 0) {
				status_width.current = oneThirdWidth
			}
			if (name_width.current === 0) {
				name_width.current = wrapWidth - SCROLL_WIDTH - oneThirdWidth * 2
			}
			const scale =
				(wrapWidth - SCROLL_WIDTH) / (name_width.current + operate_width.current + status_width.current)
			//获取到表格宽度变化后的各单元格等比变换后的值，防止出现小数误差，name_width 采用减法取剩余值
			let _operate_width = operate_width.current * scale
			let _state_width = status_width.current * scale
			let _name_width = wrapWidth - SCROLL_WIDTH - _operate_width - _state_width
			let need_reset_name = _name_width < name_min_width.current
			let need_reset_operate = _operate_width < operate_min_width
			let need_reset_state = _state_width < status_min_width.current
			/**
			 *  name_width优先级最低，其他两个达到最小值，则更改 name_width
			 *
			 */
			if (need_reset_name && need_reset_operate && need_reset_state) {
				//111
				_operate_width = operate_min_width
				_state_width = status_min_width.current
				_name_width = wrapWidth - SCROLL_WIDTH - _operate_width - _state_width
				name_min_width.current = _name_width
			} else if (need_reset_name && need_reset_operate) {
				//110
				_name_width = name_min_width.current
				_operate_width = operate_min_width
				_state_width = wrapWidth - SCROLL_WIDTH - _name_width - _operate_width
			} else if (need_reset_name && need_reset_state) {
				//101
				_name_width = name_min_width.current
				_state_width = status_min_width.current
				_operate_width = wrapWidth - SCROLL_WIDTH - _name_width - _state_width
			} else if (need_reset_operate && need_reset_state) {
				//011
				_state_width = status_min_width.current
				_operate_width = operate_min_width
				_name_width = wrapWidth - SCROLL_WIDTH - _state_width - _operate_width
			} else if (need_reset_name) {
				//100
				const tmpWidth = name_min_width.current - _name_width
				_name_width = name_min_width.current
				if (_operate_width - tmpWidth < operate_min_width) {
					_operate_width = operate_min_width
					_state_width = wrapWidth - SCROLL_WIDTH - _name_width - _operate_width
				} else {
					_operate_width = _operate_width - tmpWidth
				}
			} else if (need_reset_operate) {
				//010
				const tmpWidth = operate_min_width - _operate_width
				_operate_width = operate_min_width
				if (_name_width - tmpWidth < name_min_width.current) {
					_name_width = name_min_width.current
					_state_width = wrapWidth - SCROLL_WIDTH - _name_width - _operate_width
				} else {
					_name_width = _name_width - tmpWidth
				}
			} else if (need_reset_state) {
				//001
				const tmpWidth = status_min_width.current - _state_width
				_state_width = status_min_width.current
				if (_name_width - tmpWidth < name_min_width.current) {
					_name_width = name_min_width.current
					_operate_width = wrapWidth - SCROLL_WIDTH - _name_width - _state_width
				} else {
					_name_width = _name_width - tmpWidth
				}
			}
			//保护，防止因为初始name_width最小值的人为设定导致出现 operate或state 小于展示最小值
			if (_operate_width < operate_min_width || _state_width < status_min_width.current) {
				name_min_width.current = wrapWidth - SCROLL_WIDTH - operate_min_width - status_min_width.current
				useParamsStore.getState().refreshTableWidth()
			} else {
				operate_width.current = _operate_width
				status_width.current = _state_width
				name_width.current = _name_width
				useParamsStore.setState({
					tableWidth: {
						nameWidth: name_width.current,
						operateWidth: operate_width.current,
						statusWidth: status_width.current,
					},
				})
			}
		}
	}, [operate_min_width, refreshWidth])
	useEffect(() => {
		const handler = () => useParamsStore.getState().refreshTableWidth()
		window.addEventListener('resize', handler)
		return () => {
			window.removeEventListener('resize', handler)
		}
	}, [])
	const [onMouseDown, { showLine, lineLeftStyle }] = useEventCallback(
		(event$: Observable<React.MouseEvent<HTMLDivElement>>, state$, inputs$) =>
			event$.pipe(
				withLatestFrom(inputs$),
				switchMap(([event, [name_width, operate_width, name_min_width, operate_min_width]]) => {
					const startX = event.clientX
					return merge(
						fromEvent<MouseEvent>(window, 'mousemove').pipe(
							map((moveEvent) => {
								let offset = moveEvent.clientX - startX
								if (offset < 0) {
									if (name_width + offset < name_min_width) {
										offset = name_min_width - name_width
									}
								} else {
									if (operate_width - offset < operate_min_width) {
										offset = operate_width - operate_min_width
									}
								}
								return {
									showLine: true,
									lineLeftStyle: offset,
								}
							}),
							takeUntil(fromEvent(window, 'mouseup'))
						),
						fromEvent(window, 'mouseup').pipe(
							withLatestFrom(state$),
							map(([, { lineLeftStyle }]) => {
								return {
									showLine: false,
									lineLeftStyle,
								}
							})
						),
						of({ showLine: true, lineLeftStyle: 0 })
					)
				})
			),
		{ showLine: false, lineLeftStyle: 0 },
		[name_width.current, operate_width.current, name_min_width.current, operate_min_width]
	)
	useEffect(() => {
		if (!showLine) {
			name_width.current = name_width.current + lineLeftStyle
			operate_width.current = operate_width.current - lineLeftStyle
			useParamsStore.setState({
				tableWidth: {
					nameWidth: name_width.current,
					operateWidth: operate_width.current,
					statusWidth: status_width.current,
				},
			})
		}
	}, [showLine, lineLeftStyle])
	const [onMouseDown2, { showLine2, lineLeftStyle2 }] = useEventCallback(
		(event$: Observable<React.MouseEvent<HTMLDivElement>>, state$, inputs$) =>
			event$.pipe(
				withLatestFrom(inputs$),
				switchMap(([event, [status_width, operate_width, status_min_width, operate_min_width]]) => {
					const startX = event.clientX
					return merge(
						fromEvent<MouseEvent>(window, 'mousemove').pipe(
							map((moveEvent) => {
								let offset = moveEvent.clientX - startX
								if (offset < 0) {
									if (operate_width + offset < operate_min_width) {
										offset = operate_min_width - operate_width
									}
								} else {
									if (status_width - offset < status_min_width) {
										offset = status_width - status_min_width
									}
								}
								return {
									showLine2: true,
									lineLeftStyle2: offset,
								}
							}),
							takeUntil(fromEvent(window, 'mouseup'))
						),
						fromEvent(window, 'mouseup').pipe(
							withLatestFrom(state$),
							map(([, { lineLeftStyle2 }]) => {
								return {
									showLine2: false,
									lineLeftStyle2,
								}
							})
						),
						of({ showLine2: true, lineLeftStyle2: 0 })
					)
				})
			),
		{ showLine2: false, lineLeftStyle2: 0 },
		[status_width.current, operate_width.current, status_min_width.current, operate_min_width]
	)
	useEffect(() => {
		if (!showLine2) {
			operate_width.current = operate_width.current + lineLeftStyle2
			status_width.current = status_width.current - lineLeftStyle2
			useParamsStore.setState({
				tableWidth: {
					nameWidth: name_width.current,
					operateWidth: operate_width.current,
					statusWidth: status_width.current,
				},
			})
		}
	}, [showLine2, lineLeftStyle2])
	return [wrapRef, { onMouseDown, showLine, lineLeftStyle }, { onMouseDown2, showLine2, lineLeftStyle2 }] as const
}
